#ifndef HEAP_H
#define HEAP_H

#include <algorithm>//Para usar "fill" e "copy".
#include <cstddef>  //Para usar "size_t".
#include <cstring>  //Para usar "memcpy".
#include <iostream>
using namespace std;

typedef unsigned char byte;

/// Heap de máximo ///
class Heap
{
    private:
        /// Atributos ///
        void* vetor;
        size_t tamanho_heap;
        size_t tamanho_maximo;
        size_t tamanho_elemento;
        int(*funcao_comparacao)(const void*,const void*);

        /// Métodos privados ///
        void inicializador();                                     ///ok!

        size_t pai(size_t i);                                     ///ok!
        size_t filho_esquerdo(size_t i);                          ///ok!
        size_t filho_direito(size_t i);                           ///ok!
        // Retorna um ponteiro para o elemento na posição dada:
        void* get(size_t posicao);                                ///ok!
        // Troca o valor dos dois elementos dados:
        void trocar(size_t primeiro, size_t segundo);             ///ok!
        // Subir no heap:
        size_t heapup(size_t i);                                  ///ok!
        // Descer no heap:
        size_t heapdown(size_t i);                                ///ok!

    public:
        // Criar um heap vazio de tamanho "n":
        Heap(size_t n,// Tamanho máximo do heap.
             size_t t,// Tamanho do elemento.
             int(*comparador)(const void*,const void*)
             );                                                   ///ok!

        // Criar um heap a partir da cópia do vetor "v":
        Heap(void* v,
             size_t n,// Tamanho do vetor "v".
             size_t t,// Tamanho do elemento.
             int(*comparador)(const void*,const void*)
             );                                                   ///ok!

        // Construtor-cópia:
        Heap(const Heap& h);                                      ///ok!

        ~Heap();                                                  ///ok!

        // Trocar os valores dos atributos de duas primitivas:
        friend void trocar_atributos(Heap& pri, Heap& seg);       ///ok!
        // Operador de atribuição da classe:
        Heap& operator=(Heap h);                                  ///ok!

        size_t tamanho() const;                                   ///ok!
        size_t tamanhoMax() const;                                ///ok!

        // Criar o heap:
        void heapify();                                           ///ok!
        // Incluir elemento no heap:
        void heapoffer(void *x);                                  ///ok!
        // Remover e retornar o menor elemento do heap:
        void* heappoll();                                         ///ok!

        // Ordenar heap:
        void* heapsort();                                         ///ok!
};

#endif // HEAP_H
